#include <cstdint>
#include <string>
#include "njs_camera_capture.h"
#include "api/video/video_render_manager.h"
#include "api/video/video_sink_interface.h"
#include "modules/video_capture/video_capture_defines.h"
#include "modules/video_capture/video_capture_factory.h"
#include "modules/video_capture/ohos/device_info_ohos.h"
#include "../rtc_log.h"

namespace ohosrtc {

std::string NJSCameraCapture::GetCameraDeviceId(bool is_front) {
  std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> device_info(webrtc::VideoCaptureFactory::CreateDeviceInfo());
  if (!device_info) {
    RTC_LOG << "NJSCameraCapture device_info null";
    return "";
  }
  if (device_info->NumberOfDevices() == 0) {
    RTC_LOG << "NJSCameraCapture device_info number 0";
    return "";
  }
  char device_name[256];
  char unique_name[256];
  uint32_t position = is_front?1:0;
  if (0 == device_info->GetDeviceName(static_cast<uint32_t>(position), device_name, sizeof(device_name), unique_name, sizeof(unique_name))) {
    RTC_LOG << "NJSCameraCapture device_info GetDeviceName return null";
    return "";
  }
  RTC_LOG << "NJSCameraCapture device_info GetDeviceName return unique_name "<< unique_name;
  return unique_name;
}

NJSCameraCapture::NJSCameraCapture(int width, int height, int targetFps, std::string deviceUniqueIdUTF8)
    : width_(width), height_(height), targetFps_(targetFps), cppImpl_(webrtc::VideoCaptureFactory::Create(deviceUniqueIdUTF8.c_str())) {
  int wid = std::max(width_, height_);
  int hei = std::min(width_, height_);
  width_ = wid;
  height_ = hei;
}

bool NJSCameraCapture::StartCapture() {
  cppImpl_->RegisterCaptureDataCallback(this);
  capability_.width = static_cast<int32_t>(width_);
  capability_.height = static_cast<int32_t>(height_);
  capability_.maxFPS = static_cast<int32_t>(targetFps_);
  capability_.videoType = webrtc::VideoType::kI420;
    
  cppImpl_->SetCaptureRotation(webrtc::VideoRotation::kVideoRotation_0);
  if (cppImpl_->StartCapture(capability_) != 0) {
    StopCapture();
    return false;
  }

  RTC_CHECK(cppImpl_->CaptureStarted());
  return true;
}

void NJSCameraCapture::StopCapture() {
  RTC_CHECK(cppImpl_->CaptureStarted());
  cppImpl_->StopCapture();
  cppImpl_->DeRegisterCaptureDataCallback();
  sinks_.clear();
}

void NJSCameraCapture::SetWindowOrientation(int orientation) {}
void NJSCameraCapture::SetSensorOrientation(int orientation) {}

void NJSCameraCapture::OnFrame(const webrtc::VideoFrame &frame) {
  RTC_LOG << "NJSCameraCapture OnFrame ";
  for (const auto &listener : sinks_) {  
    listener->OnFrame(frame);
  }
}

void NJSCameraCapture::BindSink(std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink) {
  sinks_.emplace_back(std::move(sink));
}

void NJSCameraCapture::BindPreviewRender(const std::string renderId) {
  auto renderSink = webrtc::VideoRenderManager::GetInstance()->GetRender(renderId);
  sinks_.emplace_back(std::move(renderSink));
}

void NJSCameraCapture::ClearSinks() {
  sinks_.clear();
}

} // namespace ohosrtc